package com.rbcs.borrow.webapp;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.xwork.StringUtils;
import org.hibernate.criterion.MatchMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;

import com.rbcs.base.model.Item;
import com.rbcs.base.model.Project;
import com.rbcs.base.project.service.ProjectManager;
import com.rbcs.borrow.BorrowConstants;
import com.rbcs.borrow.model.Borrow;
import com.rbcs.borrow.servive.BorrowManager;
import com.rbcs.flow.FlowConstants;
import com.systop.common.modules.dept.model.Dept;
import com.systop.common.modules.dept.service.DeptManager;
import com.systop.common.modules.security.user.UserUtil;
import com.systop.common.modules.security.user.model.User;
import com.systop.core.ApplicationException;
import com.systop.core.Constants;
import com.systop.core.dao.support.Page;
import com.systop.core.util.DateUtil;
import com.systop.core.util.PageUtil;
import com.systop.core.webapp.struts2.action.JsonCrudAction;

/**
 * 借款申请管理Action
 * @author ShangHua
 *
 */
@SuppressWarnings({"serial", "unchecked", "rawtypes"})
@Controller
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class BorrowAction extends JsonCrudAction<Borrow, BorrowManager> {
	
	//部门管理Manager
	@Autowired
	private DeptManager deptManager;
	
	//项目管理Manager
	@Autowired
	private ProjectManager projectManager;
	
	//JSON数据
	private Map<String, String> jsonResult;
	
	//开始时间
	private Date startDate;

	//结束时间
	private Date endDate;
	
	//财务审批状态
	private String audStatus;
	
	//借款人Id
	private Integer borrowerId;
	
	//项目Id
	private Integer projectId; 

	//报销单里前台已选择的借款单
	private String borrowIds;
	
	//类型[判断借款单复选还是单选]
	private String type;

	/**
	 * 查询当前登录用户创建的借款申请单
	 */
	public String index(){
		Page page = PageUtil.getPage(getPageNo(), getPageSize());
		StringBuffer hql = new StringBuffer("from Borrow b where 1 = 1 ");
		List args = new ArrayList();
		User user = UserUtil.getPrincipal(getRequest());
		if (user != null) {
		
      hql.append("and b.borrower.id = ? ");
      args.add(user.getId());
		}	
		
		if (StringUtils.isNotBlank(getModel().getSingleNo())) {
			hql.append("and b.singleNo like ? ");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getSingleNo()));
		}	
		
		if (StringUtils.isNotBlank(getModel().getAudStatus())) {
			hql.append("and b.audStatus = ? ");
			args.add(getModel().getAudStatus());
		}	
		
		if (StringUtils.isNotBlank(getModel().getPayStatus())) {
			hql.append("and b.payStatus = ? ");
			args.add(getModel().getPayStatus());
		}
		commonDateCondition(hql, args);
		hql.append("order by b.createDate desc");
		page = getManager().pageQuery(page, hql.toString(), args.toArray());
		restorePageData(page);
		
		return INDEX;
	}
	
	/**
	 * 新建借款单信息
	 */
	@Override
	public String edit(){
		getModel().setCreateDate(new Date());
		if (getModel().getId() == null) {
				getModel().setDept(getLoginUserDept());

				String singleNo = DateUtil.getDateTime("yyyyMMddHHmmss", new Date());
				getModel().setSingleNo(BorrowConstants.BORROW_SINGLE_PREFIX + singleNo);
		}
		return super.edit();
	}
	
	/**
	 * 保存借款单信息
	 */
	@Override
	public String save() {
		User user = UserUtil.getPrincipal(getRequest());
		if (user != null) {
			getModel().setBorrower(user);
		} else {
			this.addActionMessage("当前登录用户信息不存在，请您重新登录系统！");
			return INPUT;
		}
    try {
    	if (getModel().getId() == null) {
    		getModel().setCreateDate(new Date());
    		getModel().setAudStatus(FlowConstants.AUDIT_UNSEND);
      	getModel().setPayStatus(Constants.NO);
      	getModel().setRePayAmount(Double.valueOf(0));
  			getModel().setDept(getLoginUserDept());
    	}
    	String projectId = getRequest().getParameter("projectId");
    	if (StringUtils.isNotBlank(projectId)) {
    		Project project = getManager().getDao().get(Project.class, Integer.valueOf(projectId));
    		getModel().setProject(project);
    	} else {
    		getModel().setProject(null);
    	}
    	String itemId = getRequest().getParameter("itemId");
    	if (StringUtils.isNotBlank(itemId)) {
    		Item item = getManager().getDao().get(Item.class, Integer.valueOf(itemId));
    		getModel().setItem(item);
    	}
  		getManager().save(getModel());
      return SUCCESS;
    } catch (Exception e) {
      addActionError(e.getMessage());
      return INPUT;
    }
	}

	/**
	 * 发送借款申请到流程表【AJAX调用】
	 * @return
	 */
	public String sendApply() {
		jsonResult = Collections.synchronizedMap(new HashMap<String, String>());
		String borrowId = getRequest().getParameter("borrowId");
		if (StringUtils.isNotBlank(borrowId)) {
			Borrow borrow = getManager().get(Integer.valueOf(borrowId));
      //判断是需要部门审批还是项目审批
			if (borrow.getProject() != null) {
				//判断是否有项目负责人
				String managerName = projectManager.checkProjectManager(borrow.getProject().getId());
				if (StringUtils.isNotBlank(managerName)) {
					jsonResult.put("result", "【" + managerName + "】没有项目负责人,不能发送申请！");
					return "jsonResult";
				}
			}else {
				//判断级联的部门是否有部门负责人
				List<Dept> depts = deptManager.getDeptsBySerialNo(getLoginUserDept().getSerialNo());
				String deptName = deptManager.checkManagerUser(depts);
				if (StringUtils.isNotBlank(deptName)) {
					deptName = deptName.substring(0, deptName.length() - 1);
					jsonResult.put("result", "【" + deptName + "】没有部门负责人,不能发送申请！");
					return "jsonResult";
				}
			}
			try{
			  getManager().saveFlows(borrow);
				jsonResult.put("result", "success");
			  } catch (Exception e) {
				e.printStackTrace();
			}
		}else {
			jsonResult.put("result", "借款申请发送失败！");
		}
		return "jsonResult";	
	}
	
	/**
	 * 删除借款单信息
	 */
	@Override
	public String remove() {
		if (getModel().getId() != null) {
			Borrow borrow = getManager().get(getModel().getId());
			getManager().remove(borrow);
		}
		return SUCCESS;
	}
	
	/**
	 * 查看借款审批信息
	 * @return
	 */
	public String view() {
		return VIEW;
	}
	
	/**
	 * 公共的日期查询条件
	 * @param hql
	 * @param args
	 */
	private void commonDateCondition(StringBuffer hql, List<Object> args) {
		if (startDate != null) {
			hql.append("and b.createDate >= ? ");
			args.add(startDate);
		}
		if (endDate != null) {
			hql.append("and b.createDate <= ? ");
			args.add(endDate);
		}
	}
	
	/**
	 * 选择出纳已付款的借款单列表
	 * @return
	 */
	public String showIndex() {
		Page page = PageUtil.getPage(getPageNo(), getPageSize());
		StringBuffer hql = new StringBuffer("from Borrow b where b.amount != b.rePayAmount");
		List args = new ArrayList();
		hql.append(" and b.audStatus = ? and b.payStatus = ? ");
		args.add(FlowConstants.AUDIT_PASS);
		args.add(Constants.YES);
		User user = UserUtil.getPrincipal(getRequest());
		if (borrowerId != null) {
      hql.append(" and b.borrower.id = ?");
      args.add(borrowerId);
		}else {
			if (user != null) {
	      hql.append(" and b.borrower.id = ?");
	      args.add(user.getId());
			}	
		}
		if (StringUtils.isNotBlank(getModel().getSingleNo())) {
			hql.append("and b.singleNo like ? ");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getSingleNo()));
		}	
    commonDateCondition(hql, args);
		hql.append("order by b.createDate desc");
		page = getManager().pageQuery(page, hql.toString(), args.toArray());
		restorePageData(page);	
		return "showIndex";
	}
	
	/**
	 * 公共的【借款参考】查询条件
	 * @param hql
	 * @param args
	 */
	private void commonReferenceCondition(StringBuffer hql, List<Object> args) {
		Page page = PageUtil.getPage(getPageNo(), getPageSize());
		hql.append(" and b.audStatus = ? and b.payStatus = ? ");
		args.add(FlowConstants.AUDIT_PASS);
		args.add(Constants.YES);
		hql.append(" order by b.createDate");
		page = getManager().pageQuery(page, hql.toString(), args.toArray());
		restorePageData(page);	
	}
	
	/**
	 * 选择出纳已付款的借款单列表【审批参考信息-业务员借款】
	 * @return
	 */
	public String selfIndex() {
		StringBuffer hql = new StringBuffer("from Borrow b where b.amount != b.rePayAmount");
		List args = new ArrayList();
    hql.append(" and b.borrower.id = ?");
    args.add(borrowerId);
		commonReferenceCondition(hql, args);	
		return "selfIndex";
	}
	
	/**
	 * 选择出纳已付款的借款单列表【审批参考信息-部门借款】
	 * @return
	 */
	public String deptIndex() {
		StringBuffer hql = new StringBuffer("from Borrow b where b.amount != b.rePayAmount and b.project.id is null");
		List args = new ArrayList();
	  hql.append(" and b.dept.serialNo like ? ");
		args.add(MatchMode.START.toMatchString(getLoginUserDept().getSerialNo()));
		commonReferenceCondition(hql, args);	
		return "deptIndex";
	}
	/**
	 * 选择出纳已付款的借款单列表【审批参考信息-项目借款】
	 * @return
	 */
	public String projectIndex() {
		StringBuffer hql = new StringBuffer("from Borrow b where b.amount != b.rePayAmount and b.project.id is not null");
		List args = new ArrayList();
		hql.append(" and b.project.id = ?");
    args.add(projectId);
		commonReferenceCondition(hql, args);	
		return "projectIndex";
	}
	
	/**
	 * 选择出纳已付款的借款单列表【审批参考信息-财务查询所有】
	 * @return
	 */
	public String financeIndex() {
		StringBuffer hql = new StringBuffer("from Borrow b where b.amount != b.rePayAmount");
		List args = new ArrayList();
		commonReferenceCondition(hql, args);	
		return "financeIndex";
	}
	
	/**
	 * 选择出纳已付款的借款单列表【报销中使用】
	 * @return
	 */
	public String selectBorrowIndex() {
		StringBuffer hql = new StringBuffer("from Borrow b where b.amount != b.rePayAmount");
		List args = new ArrayList();
		User user = UserUtil.getPrincipal(getRequest());		
		if (user != null) {
      hql.append(" and b.borrower.id = ?");
      args.add(user.getId());
		}	
		
		if(StringUtils.isNotBlank(borrowIds)) {
			hql.append(" and b.id  not in ( " + borrowIds.substring(0, borrowIds.length() - 1) + ")");
		}
		
		if (StringUtils.isNotBlank(getModel().getSingleNo())) {
			hql.append(" and b.singleNo like ?");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getSingleNo()));
		}	
	  commonDateCondition(hql, args);
		commonReferenceCondition(hql, args);	
		return "selectBorrow";
	}
	
	/**
	 * 出纳待审查询条件封装,出纳操作
	 */
	public String cashierPayIndex() {
		StringBuffer hql = new StringBuffer("from Borrow b where 1 = 1 ");
		 List<Object> args = new ArrayList<Object>();
		 // 查询部门及财务审核都已通过的借款单
		 hql.append("and b.audStatus = ? ");
		 args.add(FlowConstants.AUDIT_PASS);
		 // 根据付款状态查询
		 if (StringUtils.isNotBlank(getModel().getPayStatus())) {
		    hql.append("and b.payStatus = ? ");
		    args.add(getModel().getPayStatus());
		 }
		 if (StringUtils.isNotBlank(getModel().getSingleNo())) {
				hql.append("and b.singleNo like ? ");
				args.add(MatchMode.ANYWHERE.toMatchString(getModel().getSingleNo()));
			}	
		 commonDateCondition(hql, args);
		 hql.append("order by b.payStatus, b.createDate");
		 Page page = PageUtil.getPage(getPageNo(), getPageSize());
		 page = getManager().pageQuery(page, hql.toString(), args.toArray());
		 restorePageData(page);
		 return "cashierPayIndex";
	}
	
	/**
	 * 出纳支付【借款】
	 * @return
	 */
	@Transactional
	public String doPayBorrow() {
		if (getModel().getId() != null) {
      getModel().setPayStatus(Constants.YES);
      getManager().getDao().save(getModel());
		}
		return "doPayBorrow";
	}
	
	// 获得关联部门
	private Dept getLoginUserDept() {
		User user = UserUtil.getLoginUser(getRequest());
		user = getManager().getDao().get(User.class, user.getId());
		Dept dept = user.getDept();
		if (dept == null) {
			throw new ApplicationException("无关联部门");
		}
		return dept;
	}
	
	/**
	 * 显示借款申请部门审批状态
	 */
	public Map<String, String> getAuditStatusMap() {
		return FlowConstants.AUDIT_STATUS_MAP;
	}
	
	/**
	 * 出纳是否付款
	 */
	public Map<String, String> getIsPayMap() {
		return FlowConstants.PAY_MAP;
	}
	
  /**
   * return
   */
	public Map<String, String> getJsonResult() {
		return jsonResult;
	}

	public void setJsonResult(Map<String, String> jsonResult) {
		this.jsonResult = jsonResult;
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public String getAudStatus() {
		return audStatus;
	}

	public void setAudStatus(String audStatus) {
		this.audStatus = audStatus;
	}

	public Integer getBorrowerId() {
		return borrowerId;
	}

	public void setBorrowerId(Integer borrowerId) {
		this.borrowerId = borrowerId;
	}

	public String getBorrowIds() {
		return borrowIds;
	}

	public void setBorrowIds(String borrowIds) {
		this.borrowIds = borrowIds;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public Integer getProjectId() {
		return projectId;
	}

	public void setProjectId(Integer projectId) {
		this.projectId = projectId;
	}

}
